package com.mazaiting.web.utils;

import com.alibaba.fastjson.JSON;
import com.mazaiting.common.core.domain.result.Result;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.BusinessException;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * HTTP 工具类
 *
 * @author mazaiting
 * @create_time 2022/9/20 01:10
 */
@Slf4j
public class HttpUtil {

    /**
     * 获取请求
     *
     * @return 请求
     * @throws EmptyObjectException 空对象
     */
    public static HttpServletRequest getHttpServletRequest() throws EmptyObjectException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (ObjectUtils.isEmpty(requestAttributes)) {
            throw new EmptyObjectException(ResultCode.ACCESS_UNAUTHORIZED);
        }
        return requestAttributes.getRequest();
    }

    /**
     * 获取请求头
     * @param name 请求头名
     * @return 请求名
     */
    public static String getHeader(String name) throws EmptyObjectException {
        return getHttpServletRequest().getHeader(name);
    }

    /**
     * 下载文件
     * @param response 响应
     * @param is 输入流
     * @param fileName 文件名
     */
    public static void download(HttpServletResponse response, InputStream is, String fileName) throws BusinessException {
        try {
            setDownloadProp(response, fileName, MediaType.APPLICATION_OCTET_STREAM_VALUE);
            IOUtils.copy(is, response.getOutputStream());
        } catch (Exception e) {
            log.error("文件下载失败, 文件名: {}, 异常信息: {}.", fileName, e.getMessage());
            throw new BusinessException(ResultCode.FILE_DOWNLOAD_ERROR);
        }
    }

    /**
     * 设置下载响应
     * @param response 响应
     * @param fileName 文件名
     * @param contentType 文件类型
     */
    public static void setDownloadProp(HttpServletResponse response, String fileName, String contentType) {
        // 最后一个/
        int index = fileName.lastIndexOf("/");
        // 获取文件名
        fileName = fileName.substring(index + 1);
        // 构建下载类型
        ContentDisposition attachment = ContentDisposition.attachment().filename(URLEncoder.encode(fileName, StandardCharsets.UTF_8)).build();
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, attachment.toString());
        // 设置内容类型
        response.setContentType(contentType);
        // 设置编码
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
    }

    /**
     * 向访问者返回内容
     * @param response 响应内容
     * @param result 结果
     * @param <T> 泛型
     */
    public static <T> void writeResult(HttpServletResponse response, Result<T> result) throws IOException {        // 设置相应头
        // 设置内容类型
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        // 设置响应编码
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        // 设置跨域
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        // 设置无缓存
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
        // 塞到HttpServletResponse中返回给前台
        response.getWriter().write(JSON.toJSONString(result));
        // 刷新缓冲区
        response.flushBuffer();
    }
}
